package com.diaohw.module.file.utils;

import cn.hutool.extra.spring.SpringUtil;
import com.diaohw.module.file.obj.entity.FileDO;
import com.diaohw.platform.common.enums.CodeMsgEnum;
import com.diaohw.platform.common.util.ValueUtil;
import com.diaohw.platform.framework.redis.util.RedisSetUtil;
import io.minio.*;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author 刁海文
 * @Remark
 * @since 2023/6/15 21:53
 */
@Slf4j(topic = "Minio")
public class MinioUtil {
    protected static MinioClient client = SpringUtil.getBean(MinioClient.class);

    private static final String BUCKET = "BUCKET";

    /**
     * 校验令牌桶桑否存在
     *
     * @param bucket 令牌桶
     */
    public static boolean checkBucket(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        return client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
    }

    /**
     * 创建令牌桶能
     *
     * @param bucket 令牌桶
     */
    public static void makeBucket(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
    }

    /**
     * 文件上传
     *
     * @param stream 文件流
     * @param info   文件信息
     * @apiNote 同名且不同内容的文件会被覆盖
     */
    public static void upload(InputStream stream, FileDO info) {
        try {

            // 先校验令牌桶是否存在，不存在则创建
            createBucket(info.getBucket());
            // 上传
            PutObjectArgs build = PutObjectArgs.builder()
                    .bucket(info.getBucket())
                    .contentType(info.getContentType())
                    .object(info.path())
                    .stream(stream, stream.available(), ValueUtil.INTEGER_MINUS_ONE)
                    .build();
            client.putObject(build);
        } catch (Exception e) {
            e.printStackTrace();
            throw CodeMsgEnum.FILE.build(e.getMessage());
        }
    }


    /**
     * 下载文件
     *
     * @param bucket 令牌桶
     * @param path   文件名称
     * @return 为空时表示下载失败
     */
    public static InputStream download(String bucket, String path) {
        try {
            return client.getObject(GetObjectArgs.builder().bucket(bucket).object(path).build());
        } catch (Exception e) {
            e.printStackTrace();
            throw CodeMsgEnum.FILE.build(e.getMessage());

        }
    }

    /**
     * @param bucket   令牌桶
     * @param filename 文件名称
     * @return 操作是否成功
     */
    public static boolean delete(String bucket, String filename) {
        try {
            client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(filename).build());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 创建令牌桶
     *
     * @param bucket
     */
    private static void createBucket(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        synchronized (bucket) {
            if (RedisSetUtil.addNoExpire(BUCKET, bucket) == 0) {
                return;
            }
            boolean exists = checkBucket(bucket);
            if (exists) {
                return;
            }
            makeBucket(bucket);
        }

    }

}
